/**
 * vue3.0响应式原理：vue reactive --- proxy
 * 2.0缺点：
 * 1-默认递归 2-数组更改length无效 3-对象不存在的属性不能被拦截
 * proxy缺点：兼容性差
 */
let toProxy = new WeakMap(); //放置：原对象--代理过的对象
let toRaw = new WeakMap(); //被代理过的对象：原对象
function isObject(target) {
    return target !== null && typeof target === "object";
}
function hasOwn(target, key) {
    return target.hasOwnProperty(key);
}
function reactive(target) {
    return createReactiveObject(target);
}
function createReactiveObject(target) {
    if (!isObject(target)) {
        return target;
    }
    let proxy = toProxy.get(target);
    if (proxy) {
        return proxy;
    }
    if (toRaw.has(target)) {
        return target;
    }
    let basehandler = {
        get(target, key, receiver) {
            //    console.log('get',key)
            //收集依赖
            track(target, key); //如果此key值变化 重新让数组中的effect执行
            let res = Reflect.get(target, key, receiver);
            return isObject(res) ? reactive(res) : res;
        },

        set(target, key, value, receiver) {
            let hadKey =
                Array.isArray(target) && "" + parseInt(key, 10) === key
                    ? Number(key) < target.length
                    : hasOwn(target, key);
            let oldValue = target[key];
            let res = Reflect.set(target, key, value, receiver);

            if (!hadKey) {
                trigger(target, "add", key);
            } else if (oldValue !== value) {
                trigger(target, "set", key);
            }
            return res;
        },
        deleteProperty(target, key) {
            let res = Reflect.deleteProperty(target, key);
            return res;
        },
    };
    let observed = new Proxy(target, basehandler);
    toProxy.set(target, observed);
    toRaw.set(observed, target);
    return observed;
}
let activeEffectStacks = []; //栈型结果
let targetsMap = new WeakMap();
// {
//   target: {
//     key: [fn,fn]
//   }
// }
function track(target, key) {
    let effect = activeEffectStacks[activeEffectStacks.length - 1];
    if (effect) {
        //有对应关系才创建关联
        let depsMap = targetsMap.get(target);
        if (!depsMap) {
            targetsMap.set(target, (depsMap = new Map()));
        }
        let deps = depsMap.get(key);
        if (!deps) {
            depsMap.set(key, (deps = new Set()));
        }
        if (!deps.has(effect)) {
            deps.add(effect);
        }
    }
    //动态创建依赖关系
}
function trigger(target, type, key) {
    let depsMap = targetsMap.get(target);
    if (depsMap) {
        let deps = depsMap.get(key);
        if (deps) {
            deps.forEach((effect) => {
                effect();
            });
        }
    }
}
function effect(fn) {
    let effect = createReactiveEffect(fn);
    effect();
}
function createReactiveEffect(fn) {
    let effect = function () {
        return run(effect, fn); //1.让fn执行，2.把effect存入栈中
    };
    return effect;
}
function run(effect, fn) {
    try {
        activeEffectStacks.push(effect);
        fn();
    } finally {
        activeEffectStacks.pop();
    }
}
//依赖收集 发布订阅
let proxy = reactive({ name: "gg" });
effect(() => {
    //effect会执行两次，默认执行一次 之后依赖的数据变化了会再次执行
    console.log(proxy.name, "h");
});
proxy.name = "cc";
//如果代理过了 不需要再new了
